<template>
    <label
        class="zx-radio"
        :class="[
            border && radioSize ? 'zx-radio--' + radioSize : '',
            { 'is-disabled': isDisabled },
            { 'is-focus': focus },
            { 'is-bordered': border },
            { 'is-checked': model === label }
        ]"
        role="radio"
        :aria-checked="model === label"
        :aria-disabled="isDisabled"
        :tabindex="tabIndex"
        @keydown.space.stop.prevent="model = isDisabled ? model : label"
    >
        <span
            class="zx-radio__input"
            :class="{
                'is-disabled': isDisabled,
                'is-checked': model === label
            }"
        >
            <span class="zx-radio__inner" />
            <input
                ref="radio"
                v-model="model"
                class="zx-radio__original"
                :value="label"
                type="radio"
                aria-hidden="true"
                :name="name"
                :disabled="isDisabled"
                tabindex="-1"
                @focus="focus = true"
                @blur="focus = false"
                @change="handleChange"
            >
        </span>
        <span class="zx-radio__label" @keydown.stop>
            <slot />
            <template v-if="!$slots.default">{{ label }}</template>
        </span>
    </label>
</template>
<script>
import Emitter from '@src/mixins/emitter';

export default {
    name: 'ZxRadio',

    componentName: 'ZxRadio',

    mixins: [Emitter],

    inject: {
        zxForm: {
            default: '',
        },

        zxFormItem: {
            default: '',
        },
    },

    props: {
        value: {},
        label: {},
        disabled: Boolean,
        name: String,
        border: Boolean,
        size: String,
    },

    data() {
        return {
            focus: false,
        };
    },
    computed: {
        isGroup() {
            let parent = this.$parent;
            while (parent) {
                if (parent.$options.componentName !== 'ZxRadioGroup') {
                    parent = parent.$parent;
                } else {
                    // eslint-disable-next-line vue/no-side-effects-in-computed-properties
                    this._radioGroup = parent;
                    return true;
                }
            }
            return false;
        },
        model: {
            get() {
                return this.isGroup ? this._radioGroup.value : this.value;
            },
            set(val) {
                if (this.isGroup) {
                    this.dispatch('ZxRadioGroup', 'input', [val]);
                } else {
                    this.$emit('input', val);
                }
                this.$refs.radio && (this.$refs.radio.checked = this.model === this.label);
            },
        },
        _zxFormItemSize() {
            return (this.zxFormItem || {}).zxFormItemSize;
        },
        radioSize() {
            const temRadioSize = this.size || this._zxFormItemSize || (this.$ELEMENT || {}).size;
            return this.isGroup
                ? this._radioGroup.radioGroupSize || temRadioSize
                : temRadioSize;
        },
        isDisabled() {
            return this.isGroup
                ? this._radioGroup.disabled || this.disabled || (this.zxForm || {}).disabled
                : this.disabled || (this.zxForm || {}).disabled;
        },
        tabIndex() {
            return (this.isDisabled || (this.isGroup && this.model !== this.label)) ? -1 : 0;
        },
    },

    methods: {
        handleChange() {
            this.$nextTick(() => {
                this.$emit('change', this.model);
                this.isGroup && this.dispatch('ZxRadioGroup', 'handleChange', this.model);
            });
        },
    },
};
</script>
